package graph;

import java.awt.geom.Point2D;
import java.util.Set;

import util.Sequencer;

public class SplitableSegment implements Comparable {
	static int segIdGen = 1; // seg id generator
	int segId; // its own id
	NetworkPoint sNode, eNode;

	double[] sPoint, ePoint;
	double scoreUB, scoreLB;
	Set<Integer> containSet;
	Set<Integer> overlapSet;

	static int X = 0;
	static int Y = 1;

	/**
	 * 
	 * @param gEdge
	 */
	public SplitableSegment(NetEdgeUB gEdge) {
		segId = segIdGen++;
		this.sNode = new NetworkPoint(Sequencer.next(), gEdge.getId(), 0);
		this.eNode = new NetworkPoint(Sequencer.next(), gEdge.getId(), 1);

		this.sPoint = new double[2];
		sPoint[0] = gEdge.getSrcNode().x;
		sPoint[1] = gEdge.getSrcNode().y;

		this.ePoint = new double[2];
		ePoint[0] = gEdge.getDestNode().x;
		ePoint[1] = gEdge.getDestNode().y;

		this.scoreUB = gEdge.getScoreUB();
		this.scoreLB = gEdge.getScoreLB();
	}

	/**
	 * Constructor
	 * 
	 * @param netEdgeId
	 * @param startOnEdge
	 * @param endOnEdge
	 * @param sPoint
	 * @param ePoint
	 * @param scoreUB
	 * @param scoreLB
	 * @param containSet
	 * @param overlapSet
	 */
	public SplitableSegment(int netEdgeId, double startOnEdge,
			double endOnEdge, double[] sPoint, double[] ePoint) {
		segId = segIdGen++;
		this.sNode = new NetworkPoint(Sequencer.next(), netEdgeId, startOnEdge);
		this.eNode = new NetworkPoint(Sequencer.next(), netEdgeId, endOnEdge);

		this.sPoint = sPoint;
		this.ePoint = ePoint;
	}

	@Override
	public int compareTo(Object obj) {
		SplitableSegment e = (SplitableSegment) obj;
		if (this.scoreUB > e.scoreUB) {
			return -1;
		} else if (this.scoreUB < e.scoreUB) {
			return 1;
		} else {
			return 0;
		}
	}

	public int getSegId() {
		return segId;
	}

	public void setSegId(int segId) {
		this.segId = segId;
	}

	public int getNetEdgeId() {
		return this.sNode.getEdgeId();
	}

	public double getStartOnEdge() {
		return this.sNode.getRatioFromNode();
	}

	public double getEndOnEdge() {
		return this.eNode.getRatioFromNode();
	}

	public double[] getStartPoint() {
		return sPoint;
	}

	public void setStartPoint(double[] sPoint) {
		this.sPoint = sPoint;
	}

	public double[] getEndPoint() {
		return ePoint;
	}

	public void setEndPoint(double[] ePoint) {
		this.ePoint = ePoint;
	}

	public double getScoreUB() {
		return scoreUB;
	}

	public void setScoreUB(double scoreUB) {
		this.scoreUB = scoreUB;
	}

	public double getScoreLB() {
		return scoreLB;
	}

	public void setScoreLB(double scoreLB) {
		this.scoreLB = scoreLB;
	}

	public Set<Integer> getContainSet() {
		return containSet;
	}

	public void setContainSet(Set<Integer> containSet) {
		this.containSet = containSet;
	}

	public Set<Integer> getOverlapSet() {
		return overlapSet;
	}

	public void setOverlapSet(Set<Integer> overlapSet) {
		this.overlapSet = overlapSet;

	}

	public NetworkPoint getsNode() {
		return sNode;
	}

	public NetworkPoint geteNode() {
		return eNode;
	}

	public double[] getsPoint() {
		return sPoint;
	}

	public double[] getePoint() {
		return ePoint;
	}

	public String toString() {
		return "SS" + this.segId + ": eid=" + this.getNetEdgeId() + ";relPos=("
				+ this.getStartOnEdge() + "," + this.getEndOnEdge() + "); lb="
				+ this.scoreLB + " ub=" + this.scoreUB + "; sPoint=("
				+ sPoint[0] + "," + sPoint[1] + "); ePoint=(" + ePoint[0] + ","
				+ ePoint[1] + ")";
	}

	double[][] getBoundingBox() {
		int dim = 2;
		double xmin = Math.min(this.getStartPoint()[X], this.getEndPoint()[X]);
		double xmax = Math.max(this.getStartPoint()[X], this.getEndPoint()[X]);
		double ymin = Math.min(this.getStartPoint()[Y], this.getEndPoint()[Y]);
		double ymax = Math.max(this.getStartPoint()[Y], this.getEndPoint()[Y]);

		double[] p1 = { xmin, ymin };
		double[] p2 = { xmax, ymax };

		double[][] res = new double[dim][dim];
		res[0] = p1;
		res[1] = p2;
		return res;
	}
}
